﻿/**
 * Licensed to Open-Ones Group under one or more contributor license
 * agreements. See the NOTICE file distributed with this work
 * for additional information regarding copyright ownership.
 * Open-Ones Group licenses this file to you under the Apache License,
 * Version 2.0 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a
 * copy of the License at:
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
namespace IPresenter
{
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Threading;
    using System.Windows.Forms;

    /// <summary>
    /// Manage threads in application
    /// </summary>
    public static class Threads
    {
        /// <summary>
        /// Thread Name
        /// </summary>
        public const string SERVER_NETWORK = "serverwifi";

        /// <summary>
        /// Thread Name
        /// </summary>
        public const string SERVER_BLUETOOTH = "serverbluetooth";

        /// <summary>
        /// Thread Name
        /// </summary>
        public const string CLIENT_PROGRESS_BAR = "clientprogressbar";

        /// <summary>
        /// Thread Name
        /// </summary>
        public const string CLIENT_NETWORK = "clientwifi";

        /// <summary>
        /// Thread which run process listen and receive message on server via wifi
        /// </summary>
        private static Thread ServerNetworkListening;

        /// <summary>
        /// Thread which run process listen and receive message on client via wifi
        /// </summary>
        private static Thread ClientNetworkListening;

        /// <summary>
        /// Thread which run process listen and receive message on server via bluetooth
        /// </summary>
        private static Thread ServerBluetoothListening;

        /// <summary>
        /// Thread which run process scan PC network on Client
        /// </summary>
        private static Thread ClientGetNetworkRunning;

        /// <summary>
        /// Array which will dertemine which thread is turned on or off.
        /// </summary>
        private static List<int> ArrayThread;

        /// <summary>
        /// Thread which run process listen and receive message on client via bluetooth
        /// </summary>
        private static Thread ClientBluetoothListening;

        /// <summary>
        /// Gets or sets ArrayThread
        /// </summary>
        public static List<int> ArrayThreads
        {
            get { return ArrayThread; }
            set { ArrayThread = value; }
        }

        /// <summary>
        /// Gets or sets thread which is used to run process of listening at server via network. 
        /// </summary>
        public static Thread ServerNetwork
        {
            get { return Threads.ServerNetworkListening; }
            set { Threads.ServerNetworkListening = value; }
        }
    
        /// <summary>
        /// Gets or sets thread which is used to run process of listening at client via network
        /// </summary>
        public static Thread ClientNetwork
        {
            get { return Threads.ClientNetworkListening; }
            set { Threads.ClientNetworkListening = value; }
        }

        /// <summary>
        /// Gets or sets thread which is used to run process of listening at server via bluetooth
        /// </summary>
        public static Thread ServerBluetooth
        {
            get { return Threads.ServerBluetoothListening; }
            set { Threads.ServerBluetoothListening = value; }
        }

         /// <summary>
        /// Gets or sets thread which is used to run process of listening at client via client
        /// </summary>
        public static Thread ClientBluetooth
        {
            get { return Threads.ClientBluetoothListening; }
            set { Threads.ClientBluetoothListening = value; }
        }

        /// <summary>
        /// Gets or sets thread which is used to run process scan PC network at client via network.
        /// </summary>
        public static Thread ClientGetNetwork
        {
            get { return Threads.ClientGetNetworkRunning; }
            set { Threads.ClientGetNetworkRunning = value; }
        }

        /// <summary>
        /// Run thread
        /// </summary>
        /// <param name="obj">Object server or client</param>
        /// <param name="kindOfThread">Name Thread</param>
        public static void Start(object obj, string kindOfThread)
        {
            ThreadStart threadStart;
            ServerIPresenter svServer = new ServerIPresenter();
            try
            {
                if (kindOfThread == SERVER_NETWORK || kindOfThread == SERVER_BLUETOOTH)
                {
                    svServer = (ServerIPresenter)obj;
                }

                switch (kindOfThread)
                {
                    case SERVER_NETWORK:
                        threadStart = new ThreadStart(svServer.AcceptNetwork);
                        ServerNetwork = new Thread(threadStart);
                        ServerNetwork.Start();
                        SwitchThread(1,true);
                        break;
                    case SERVER_BLUETOOTH:
                        threadStart = new ThreadStart(svServer.AcceptBlueTooth);
                        ServerBluetooth = new Thread(threadStart);
                        ServerBluetooth.Start();
                        SwitchThread(2,true);
                        break;
                    case CLIENT_PROGRESS_BAR:
                        IPresenter ipreMainForm = new IPresenter();
                        ipreMainForm = (IPresenter)obj;
                        threadStart = new ThreadStart(ipreMainForm.GetNetworkComputers);
                        ClientGetNetwork = new Thread(threadStart);
                        ClientGetNetwork.Start();
                        SwitchThread(3,true);
                        break;
                    case CLIENT_NETWORK:
                        ClientIPresenter clClient = new ClientIPresenter();
                        clClient = (ClientIPresenter)obj;
                        threadStart = new ThreadStart(clClient.Connect);
                        ClientNetwork = new Thread(threadStart);
                        ClientNetwork.Start();
                        SwitchThread(4, true);
                        break;
                    default:
                        Logs.WriteErrorMessage("Kind of thread is not exist");
                        break;
                }
            }
            catch (Exception ex)
            {
                Logs.WriteErrorMessage(ex.Message);
            }
        }

        /// <summary>
        /// Dispose all thread
        /// </summary>
        public static void Dispose()
        {
            try
            {
                for (int i = 0; i < ArrayThread.Count; i++)
                {
                    if (ArrayThread[i] == 1)
                    {
                        ServerNetwork.Abort();
                        Logs.WriteErrorMessage("Abort ServerNetWork sucessfully");
                    }

                    if (ArrayThread[i] == 2)
                    {
                        ServerBluetooth.Abort();
                        Logs.WriteErrorMessage("Abort ServerNetWork sucessfully");
                    }

                    if (ArrayThread[i] == 3)
                    {
                        ClientGetNetwork.Abort();
                        Logs.WriteErrorMessage("Abort ServerNetWork sucessfully");
                    }

                    if (ArrayThread[i] == 4)
                    {
                        ClientNetwork.Abort();
                        Logs.WriteErrorMessage("Abort ServerNetWork sucessfully");
                    }
                }
                ArrayThread.Clear();
            }
            catch (Exception ex)
            {
                Logs.WriteErrorMessage(ex.Message);
            }
        }

        /// <summary>
        /// Turn on or off thread
        /// </summary>
        /// <param name="position">Position of thread whose you would like to turn on</param>
        /// <param name="enable">
        /// true: enable
        /// false: disable
        /// </param>
        /// <returns>
        /// true: success
        /// false: unsuccess
        /// </returns>
        public static bool SwitchThread(int position,bool enable)
        {
            if (position > 0)
            {
                try
                {
                    if (ArrayThread.Contains(position) == false && enable == true)
                    {
                        ArrayThread.Add(position);
                        return true;
                    }
                    if (ArrayThread.Contains(position) == true && enable == false)
                    {
                        ArrayThread.RemoveAt(ArrayThread.IndexOf(position));
                        return true;
                    }
                }
                catch (Exception ex)
                {
                    Logs.WriteErrorMessage(ex.Message);
                }
                return false;
            }

            return false;
        }
    }
}
